package main

import (
	"container/list"
	"encoding/json"
	"fmt"
	"monitor-control/config"
	"monitor-control/monitor"
	"strconv"
	"sync"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/giorgisio/goav/avformat"
)

type recordInput struct {
	Id         int64
	Handler    int
	Camip      string
	RecordTime int64
}

type callBackResult struct {
	Code int64
	Message string
}
/*
func main() {
	var i_fmt_ctx *avformat.Context
	res := monitor.ConnHandler("rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov", &i_fmt_ctx)
	fmt.Println(res)
	i_fmt_ctx=nil
	res = monitor.ConnHandler("rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov", &i_fmt_ctx)
	fmt.Println(res)
	for {

	}
}
*/

func main() {

	var dict map[string]*monitor.CamContext
	dict = make(map[string]*monitor.CamContext)

	configData := config.Init()
	//ticker := time.NewTicker(time.Second * 60)

	for item := configData.CamList.Front(); nil != item; item = item.Next() {
			cma := item.Value.(config.CmaConfig)
			var i_fmt_ctx *avformat.Context
			flag := true
		go func() {
			var dataList *list.List = list.New()
			var link bool = false
			lock := new(sync.RWMutex)
			dict[cma.Ip] = &monitor.CamContext{&i_fmt_ctx, &dataList, lock,&link}
			cam:= dict[cma.Ip]
			res := monitor.ConnHandler(cma.In, &i_fmt_ctx,cam)
			if res < 0 {
				for res < 0 {
					fmt.Println(cma.In+"连接失败尝试重连")
					res = monitor.ConnHandler(cma.In, &i_fmt_ctx,cam)
				}
			}
			link = true
			//i_fmt_ctx.AvDumpFormat(0, "rtsp://192.168.0.80:50000/video", 0)
			go monitor.RtspData(cma.In,i_fmt_ctx, &dataList, &flag,&link,lock,cam)
			go func() {
				ticker := time.NewTicker(time.Second * 60)
				for range ticker.C {
					if !link {
						fmt.Println("连接中断跳过清除")
						continue
					}
					vP := dict[cma.Ip]
					fmt.Println("缓存清理开始:" + cma.Ip + "获取锁")
					v := *vP
					v.Lock.Lock()

					var data *list.List = *v.DataList
					if data.Len() != 0 {
						current := data.Back().Value.(monitor.DataPacket)
						currentTime := current.PlayTime
						if currentTime < 30 {

						} else {
							end := currentTime - 30
							var next *list.Element
							if end > 0 {
								for e := data.Front(); e != nil; e = next {
									if link {
										next = e.Next()
										value := e.Value.(monitor.DataPacket)
										if value.PlayTime < end {
											value.AvPacketUnref()
											data.Remove(e)
											//fmt.Println("缓存清理:" + strconv.FormatInt(value.PlayTime, 10))
										}	
									} else {
										fmt.Println("缓存定时检测到连接中断")
										break
									}
									
								}
							}
						}

					}
					v.Lock.Unlock()
					fmt.Println("缓存清理开始:" + cma.Ip + "释放锁")

				}
			}()

		}()
	}

	/*
	go func() {
		for range ticker.C {
			//fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
			for k, v := range dict {
				//fmt.Println(k, v)
				fmt.Println("缓存清理开始:" + k + "获取锁")
				v.Lock.Lock()

				var data *list.List = *v.DataList
				if data.Len() != 0 {
					current := data.Back().Value.(monitor.DataPacket)
					currentTime := current.PlayTime
					if currentTime < 30 {

					} else {
						end := currentTime - 30
						var next *list.Element
						if end > 0 {
							for e := data.Front(); e != nil; e = next {
								next = e.Next()
								value := e.Value.(monitor.DataPacket)
								if value.PlayTime < end {
									value.AvPacketUnref()
									data.Remove(e)
									//fmt.Println("缓存清理:" + strconv.FormatInt(value.PlayTime, 10))
								}	
							}
						}
					}

				}
				v.Lock.Unlock()
				fmt.Println("缓存清理开始:" + k + "释放锁")

			}

		}
	}()
	*/

	//monitor.monitorStart("rtsp://192.168.0.80:50000/video", &i_fmt_ctx, &dataList, &flag)
	r := gin.Default()
	/*
		r.GET("/ping", func(c *gin.Context) {
			go monitor.CreateFileMp4("media.mp4", i_fmt_ctx, &dataList, 10)
			c.JSON(200, gin.H{
				"message": "pong",
			})
		})
	*/
	r.POST("/api/video/record", func(c *gin.Context) {
		//id := c.PostForm("id")
		//handler := c.PostForm("handler")
		//camip := c.PostForm("camip")
		//recordTime := c.PostForm("recordTime")

		//nick := c.DefaultPostForm("nick", "anonymous") // 此方法可以设置默认值
		buf := make([]byte, 1024)
		n, _ := c.Request.Body.Read(buf)
		//fmt.Println(string(buf[0:n]))
		input := recordInput{}
		json.Unmarshal(buf[0:n], &input)
		//fmt.Println()
		fmt.Println("post接收参数:ip:"+input.Camip+"id:"+strconv.FormatInt(input.Id, 10))
		cam, ok := dict[input.Camip]
		result := callBackResult{1,"开始录制"}
		if ok {
			if *cam.Link {
				go monitor.CreateFileMp4(configData.FileName+strconv.FormatInt(input.Id, 10)+"-media.mp4",input.Id,input.Camip ,*cam.IfmtCtx, cam.DataList, strconv.FormatInt(input.Id, 10)+"-media.mp4", input.RecordTime, cam.Lock,cam.Link)
			} else {
				result = callBackResult{3,"摄像头断开连接"}
			}
			
	
		} else {
			fmt.Println("没有找到摄像头")
			result = callBackResult{2,"没有找到摄像头"}
		}
		c.JSON(200, gin.H{
			"result": result,
		})
	})
	r.Run(":"+strconv.FormatInt(configData.Port,10)) // listen and serve on 0.0.0.0:8080
}
